import os
import random
import re
import sys

from django.http import HttpResponse, HttpResponseForbidden
from django.views import View
from django_redis import get_redis_connection
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import AllowAny

from libs.captcha.captcha import captcha
from libs.rl_sms import send_message

# 随机生成图片验证码接口
class ImageCodeView(View):
    def get(self, request):
        """
        请求获取图片接口, 是普通类视图, 需要一个uuid参数, 用来关联图片
        :param request:
        :return:
        """
        # 接收数据
        uuid = request.GET.get('uuid')

        # 校验数据
        if not uuid:
            return HttpResponseForbidden('uuid无效')

        # 处理业务
        # 获取图片文本内容和图片二进制代码
        text, image = captcha.generate_captcha()

        # 把uuid和图片文本存入redis
        # 获取redis客户端,
        redis_client = get_redis_connection('verify_code')
        # 写入redis
        redis_client.setex(uuid, 60 * 5, text)

        #  返回响应
        return HttpResponse(image, content_type='image/jpg')

# 验证图形验证码及手机验证码
class SmsCodeView(APIView):
    # 使用apiview限流(所有人可访问)
    # permission_classes = (AllowAny,)
    def post(self,request):
        # 获取手机号
        phone = request.data.get('phone')
        # 获取图形验证码
        image_code = request.data.get('image_code')
        # 获取随机uuid
        image_code_uuid = request.data.get('image_code_uuid')
        
        #  检查参数
        if not all([phone, image_code, image_code_uuid]):
            return Response({"code": 403, "msg": "参数不全"})

        #  检查是否发送
        redis_client = get_redis_connection('verify_code')
        phone_exists = redis_client.get(phone)
        # if phone_exists:
        #     return Response({"code": 403, "msg": "频繁发送, 请稍后再试"})

        # 验证图形验证码
        redis_image_code = redis_client.get(image_code_uuid)  # bytes
        if redis_image_code:
            # bytes 转成 string
            redis_image_code = redis_image_code.decode()

        # 比较用户提供的图片内容是否和redis中保存的一致(upper将验证码都已大写格式存储)
        if image_code.upper() != redis_image_code:
            return Response({'code': 403, 'msg': '图片验证码不正确'})


        # # celery异步发送
        # code = '%06d' % random.randint(0, 999999)  # 随机6位验证码
        # # 这里导包必须导在方法里
        # from mydjango.settings import BASE_DIR
        # # 指定包的位置
        # sys.path.insert(0, os.path.join(BASE_DIR, '../celery_task'))
        # from main import send_sms_code

        # send_sms_code.delay(phone, (code, "5"))

        # send_sms_code(phone, (code, "5")

        #  发送
        code = '%06d' % random.randint(0, 999999)  # 随机6位验证码
        send_resp = send_message(phone, (code, "5"))  # 0 : 成功, -1: 失败
        if send_resp == '-1':
            return Response({"code": 403, "msg": "短信发送失败"})

        #  保存code 到 redis中
        redis_client.setex(phone, 60 * 5, code)  # phone:code, 5分钟有效期

        #  从redis中删除这个图片验证码, 以防再次被使用
        redis_client.delete(image_code_uuid)

        # 使用 pipeline 批量操作
        pl = redis_client.pipeline()
        pl.setex(phone, 60 * 5, code)
        pl.delete(image_code_uuid)
        pl.execute()

        # 返回结果
        return Response({"code": 200, "msg": "短信发送成功"})